﻿using System;
using Super_Management_Mayhem.Content.Spritesheet;
using Super_Management_Mayhem.Screens.Playing.AttackModel;
using Super_Management_Mayhem.Screens.Playing.ObjectInterfaces;
using Super_Management_Mayhem.Screens.Playing.Particle.RandomObjectExplosion;
using Super_Management_Mayhem.Screens.Playing.Players;
using Super_Management_Mayhem.Screens.Playing.Players.Manager;
using Transformable_Engine_v2.Engine.Animation.PositionAnimation;
using Transformable_Engine_v2.Engine.Animation.Trajectory;
using Transformable_Engine_v2.Engine.GameObjects.Containers;
using Transformable_Engine_v2.Engine.Graphics;
using Transformable_Engine_v2.Engine.Helper;
using Transformable_Engine_v2.Engine.Time;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Super_Management_Mayhem.Screens.Playing.Items
{
    public class ThrownRandomObject : Container, IOrderable, IAttacker
    {
        private static readonly TE_Rectangle HitBox = new TE_Rectangle(0, 0, 1, 1, TE_Rectangle.Alignment.CenterMiddle).ToGridBound();
        private ItemSheet.RandomObjectItems _itemType;

        private BaseAttack _attack;

        public ThrownRandomObject(ItemSheet.RandomObjectItems randomItem, TE_Vector2 direction, Team team)
        {
            _attack = new RadialAttack(BaseAttack.TargetTeam.EnemyTo, team, this, 6, 300, HitBox, 16);

            _itemType = randomItem;

            var item = new ImageContainer
            {
                Sprite = ItemSheet.GetSprite(randomItem),
                Origin = TE_Rectangle.Alignment.CenterMiddle
            };

            AddChildren(item);

            AddAnimations(new PositionAnimation(new BounceEasing(BaseTrajectory.Easing.EaseOut), new TE_Vector2(0, 1.5f), 600, false, 0));
            AddAnimations(new PositionAnimation(new QuadraticEasing(BaseTrajectory.Easing.EaseOut), direction * 6, 600, false, 0));
            Die(500);
        }

        public override void FixedStepUpdate(TimeSpan gameTime)
        {
            _attack.Attack(AbsolutePosition);

            base.FixedStepUpdate(gameTime);
        }

        public float GetOrderingFactor()
        {
            return Position.Y;
        }

        public override void Die()
        {
            Playscreen.Map.AddParticle(new RandomObjectExplosion { Position = AbsolutePosition });

            switch(_itemType)
            {
                case ItemSheet.RandomObjectItems.Range:
                    Playscreen.Map.AddItem(new ClassChanger(ItemSheet.Classes.Range) { Position = AbsolutePosition });
                    break;
                case ItemSheet.RandomObjectItems.Points:
                    Playscreen.Map.TossPoints(50, AbsolutePosition, null);
                    break;
                case ItemSheet.RandomObjectItems.Power:
                    Playscreen.Map.AddItem(new ClassChanger(ItemSheet.Classes.Power) { Position = AbsolutePosition });
                    break;
                case ItemSheet.RandomObjectItems.Magic:
                    Playscreen.Map.AddItem(new ClassChanger(ItemSheet.Classes.Magic) { Position = AbsolutePosition });
                    break;
                case ItemSheet.RandomObjectItems.Damage:
                    Playscreen.Map.AddItem(new ClassChanger(ItemSheet.Classes.Damage) { Position = AbsolutePosition });
                    break;
                case ItemSheet.RandomObjectItems.Utility:
                    Playscreen.Map.AddItem(new ClassChanger(ItemSheet.Classes.Utility) { Position = AbsolutePosition });
                    break;
                case ItemSheet.RandomObjectItems.Random:
                    Playscreen.Map.AddItem(new ClassChanger(ItemSheet.Classes.Random) { Position = AbsolutePosition });
                    break;
            }

            base.Die();
        }

        public IAttacker GetReference()
        {
            return this;
        }

        public void OnAttack()
        {
        }
    }

    public class PickedUpRandomObject : Container, IThrowable
    {
        private int _currentItem;

        private const int RANDOM_TIME = 500;

        private ImageContainer _item;

        public override void LoadContent()
        {
            _item = new ImageContainer {
                                              Sprite = ItemSheet.GetSprite(ItemSheet.Item.Random),
                                              Origin = TE_Rectangle.Alignment.CenterMiddle
                                          };

            AddChildren(_item);
            AddTimers(new Timer(RANDOM_TIME, true, RandomizeItem).AutoStart());

            _currentItem = -1;
            RandomizeItem();
        }

        void RandomizeItem()
        {
            int newItem = Randomizer.Int((int) ItemSheet.RandomObjectItems.Count - 1);

            if(newItem == _currentItem)
            {
                newItem = (_currentItem + 1) % (int) ItemSheet.RandomObjectItems.Count;
            }

            _item.Sprite = ItemSheet.GetSprite((ItemSheet.RandomObjectItems) newItem);

            _currentItem = newItem;
        }

        public void Throw(TE_Vector2 throwerPosition, TE_Vector2 itemPosition, Manager.Direction latestDirection, Team team)
        {
            TE_Vector2 direction = null;

            switch (latestDirection)
            {
                case Manager.Direction.Up:
                    direction = -TE_Vector2.UnitY;
                    break;
                case Manager.Direction.Down:
                    direction = TE_Vector2.UnitY;
                    break;
                case Manager.Direction.Left:
                    direction = -TE_Vector2.UnitX;
                    break;
                case Manager.Direction.Right:
                    direction = TE_Vector2.UnitX;
                    break;
            }

            Playscreen.Map.AddItem(new ThrownRandomObject((ItemSheet.RandomObjectItems) _currentItem, direction, team) { Position = itemPosition });
        }
    }

    public class RandomObject : BasePickableItem
    {
        protected override int ReappearTime
        {
            get
            {
                return 10000;
            }
        }

        public override void LoadContent()
        {
            _item = new ImageContainer {
                                           Sprite = ItemSheet.GetSprite(ItemSheet.Item.Random),
                                           PositionGridBound = new TE_Vector2(0, -0.25f)
                                       };

            _item.AddAnimations(
                new PositionAnimation(new SinusTrajectory(), new TE_Vector2(0, -0.50f), 1000, true, 0));

            _outline = new ImageContainer {
                                              Sprite = ItemSheet.GetSprite(ItemSheet.ItemOutline.RandomOutline),
                                              PositionGridBound = new TE_Vector2(0, -0.25f)
                                          };

            _outline.AddAnimations(
                new PositionAnimation(new SinusTrajectory(), new TE_Vector2(0, -0.50f), 1000, true, 0));

            AddChildren(_item, _outline);


            base.LoadContent();
        }

        protected override IThrowable GetPickupItem()
        {
            return new PickedUpRandomObject();
        }
    }
}
